#ifdef HAVE_CONFIG_H
#   include "config.h"
#endif

#include "CEGUI.h"
#include "CEGuiSample.h"

// includes for application types
#ifdef CEGUI_SAMPLES_USE_OPENGL
#   include "CEGuiOpenGLBaseApplication.h"
#endif

// Include iostream if not on windows.
#if defined( __WIN32__ ) || defined( _WIN32 )
#   ifdef CEGUI_SAMPLES_USE_DIRECTX_9
#       include "CEGuiD3D9BaseApplication.h"
#   endif
#   ifdef CEGUI_SAMPLES_USE_DIRECTX_10
#       include "CEGuiD3D10BaseApplication.h"
#   endif
#   ifdef CEGUI_SAMPLES_USE_DIRECTX_11
#       include "CEGuiD3D11BaseApplication.h"
#   endif
#endif

/*************************************************************************
    Constructor
*************************************************************************/
CEGuiSample::CEGuiSample() :
        d_sampleApp(0)
{}


/*************************************************************************
    Destructor
*************************************************************************/
CEGuiSample::~CEGuiSample()
{
    if (d_sampleApp)
    {
        d_sampleApp->cleanup();
        delete d_sampleApp;
    }

}


/*************************************************************************
    Application entry point
*************************************************************************/
int CEGuiSample::run()
{
    CEGUI_TRY
    {
        if (initialise())
            cleanup();
    }
    CEGUI_CATCH (CEGUI::Exception& exc)
    {
        outputExceptionMessage(exc.getMessage().c_str());
    }
    CEGUI_CATCH (std::exception& exc)
    {
        outputExceptionMessage(exc.what());
    }
    CEGUI_CATCH (const char* exc)
    {
        outputExceptionMessage(exc);
    }
    CEGUI_CATCH(...)
    {
        outputExceptionMessage("Unknown exception was caught!");
    }

    return 0;
}


/*************************************************************************
    Initialise the sample application
*************************************************************************/
bool CEGuiSample::initialise()
{
#define CEGUI_SAMPLES_USE_DIRECTX_10

    d_sampleApp = new CEGuiD3D10BaseApplication();

    // execute the base application (which sets up the demo via 'this' and runs it.
    if (d_sampleApp->execute(this))
    {
        // signal that app initialised and ran
        return true;
    }

    // sample app did not initialise, delete the object.
    delete d_sampleApp;
    d_sampleApp = 0;



    // signal app did not initialise and run.
    return false;
}


/*************************************************************************
    Cleanup the sample application.
*************************************************************************/
void CEGuiSample::cleanup()
{
    if (d_sampleApp)
    {
        d_sampleApp->cleanup();
        delete d_sampleApp;
        d_sampleApp = 0;
    }

}


/*************************************************************************
    Output a message to the user in some OS independant way.
*************************************************************************/
void CEGuiSample::outputExceptionMessage(const char* message) const
{
#if defined(__WIN32__) || defined(_WIN32)
    MessageBoxA(0, message, "CEGUI - Exception", MB_OK|MB_ICONERROR);
#else
    std::cout << "An exception was thrown within the sample framework:" << std::endl;
    std::cout << message << std::endl;
#endif
}
